# 补全算法
import math
from io import BytesIO
from typing import List
from seaman.core import JsonUtil
import pandas as pd
from minio import Minio

from algs.common import OilWellData, get_delta_depth, get_delta_azimuth

# 创建Minio客户端对象
client = Minio(
    endpoint="10.105.10.193:9000",
    access_key="vIDqbXGCUUO2qkAgpF5A",
    secret_key="Lk8Yu4A9JOPCsGHhRJHDCpbEGy4WHCPiYiazPujm",
    secure=False  # 如果使用HTTPS，则设置为True
)


# client = Minio(
#     endpoint="127.0.0.1:9000",
#     access_key="wr8s9pEfDZu5j6k8qnwB",
#     secret_key="vaUescIBViPyek84IF3abRUvkEMRALwAkxkAzA2t",
#     secure=False  # 如果使用HTTPS，则设置为True
# )

# X 计算
# a 为需要填充的数据 N_i b为已知数据 N_(i-1)
def get_north(a: OilWellData, b: OilWellData) -> float:
    # 偏移 north 计算
    delta_north: float = get_delta_north(a, b)
    # print('深度增量', a.depth, delta_north)
    # 最终结果
    north: float = b.north + delta_north
    # 返回
    return north


# X 偏移量计算
# a 为需要填充的数据 Data_i b为已知数据 Data_(i-1)
def get_delta_north(a: OilWellData, b: OilWellData) -> float:
    # print('计算系数为:',get_delta_factor(a, b))
    return get_delta_factor(a, b) * (math.sin(math.radians(b.inclination)) * math.cos(math.radians(b.azimuth)) +
                                     math.sin(math.radians(a.inclination)) * math.cos(math.radians(a.azimuth)))


# Y 计算
def get_east(a: OilWellData, b: OilWellData) -> float:
    # 偏移 east 计算
    delta_east: float = get_delta_east(a, b)
    # 最终结果
    east: float = b.east + delta_east
    # 返回
    return east


# Y 偏移量计算
def get_delta_east(a: OilWellData, b: OilWellData) -> float:
    return get_delta_factor(a, b) * (math.sin(math.radians(a.inclination)) * math.sin(math.radians(a.azimuth)) +
                                     math.sin(math.radians(b.inclination)) * math.sin(math.radians(b.azimuth)))


# Z 坐标计算
def get_true_vertical_depth(a: OilWellData, b: OilWellData) -> float:
    # 偏移 tvd 计算
    delta_true_vertical_depth: float = get_delta_true_vertical_depth(a, b)
    # 最终结果
    true_vertical_depth = delta_true_vertical_depth + b.true_vertical_depth
    # 返回
    return true_vertical_depth


# 计算 Z 偏移量
def get_delta_true_vertical_depth(a: OilWellData, b: OilWellData) -> float:
    return get_delta_factor(a, b) * (math.cos(math.radians(a.inclination)) + math.cos(math.radians(b.inclination)))


# 偏移量计算系数
def get_delta_factor(a: OilWellData, b: OilWellData) -> float:
    # print(get_delta_depth(a, b))
    # print(JsonUtil.obj2str(a))
    # print(JsonUtil.obj2str(b))
    full_angle: float = get_full_angle(a, b)
    # print("全角弧度", math.radians(full_angle))
    # 如果全角 = 0
    if full_angle.__eq__(0.0):
        return get_delta_depth(a, b) * 0.5
    else:
        # 180/PI
        return ((180 * math.pow(math.pi, -1))
                * (get_delta_depth(a, b) * math.pow(full_angle, -1))
                * math.tan(math.radians(full_angle * 0.5)))


# 计算全角
def get_full_angle(a: OilWellData, b: OilWellData) -> float:
    # 定义计算元
    factor_a: float = math.cos(math.radians(b.inclination)) * math.cos(math.radians(a.inclination))
    factor_b: float = math.sin(math.radians(b.inclination)) * math.sin(math.radians(a.inclination)) * math.cos(
        math.radians(get_delta_azimuth(a, b))
    )
    # print(a.depth)
    # print("### completion.py 102 ###########")
    # print( factor_a + factor_b)
    t: float = factor_a + factor_b
    if t >= 1.0:
        t = 0.9999999999
    factor_res: float = math.acos(t)
    return math.degrees(factor_res)
    # return math.acos(math.cos(b.inclination) * math.cos(a.inclination) +
    #                  math.sin(b.inclination) * math.sin(a.inclination) * math.cos(get_delta_azimuth(a, b)))


# 获得补全数据
def get_completion_data(_list_: List[OilWellData]) -> List[OilWellData]:
    data_size = len(_list_)
    for idx in range(1, data_size):
        _list_[idx].north = get_north(_list_[idx], _list_[idx - 1])
        _list_[idx].east = get_east(_list_[idx], _list_[idx - 1])
        _list_[idx].true_vertical_depth = get_true_vertical_depth(_list_[idx], _list_[idx - 1])
        # print(JsonUtil.obj2str(oil_data_list[idx]))
    for idx in range(0, data_size):
        _list_[idx].north = round(_list_[idx].north, 2)
        _list_[idx].east = round(_list_[idx].east, 2)
        _list_[idx].true_vertical_depth = round(_list_[idx].true_vertical_depth, 2)
        # print(JsonUtil.obj2str(_list_[idx]))
    return _list_


# 获取补全数据 导出Excel
def export_complete_data(_list_: List[OilWellData]) -> List[OilWellData]:
    # 补全数据
    _list_ = get_completion_data(_list_)
    # print(_list_)
    return _list_


# main
if __name__ == '__main__':
    file_data = client.get_object('well', '1676865706773319680.xlsx')
    df = pd.read_excel(BytesIO(file_data.read()))
    data_list: List[OilWellData] = []
    for index, row in df.iterrows():
        item: OilWellData = OilWellData()
        item.depth = row['depth']
        item.inclination = row['inclination']
        item.azimuth = row['azimuth']
        if index.__eq__(0):
            item.north = 0.0
            item.east = 0.0
            item.true_vertical_depth = item.depth
        data_list.append(item)
    # 执行
    get_completion_data(data_list)
